﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Threading;
using System.Windows.Threading;
using SLS.ExClassLib.Events;
using SLS.ExClassLib.ExThreading;
using SLS.ExClassLib.Message;
using SLS.Core.HLASimu;
namespace SLS.ExClassLib.Event
{ 
    public partial class EventDispatcher : DispatcherObject
    {
        #region =================SINGLETON=================
        public static readonly EventDispatcher Instance = new EventDispatcher();
        public delegate void ExThreadDelegate(MessageEx msg);
        ArrayList Federation;
        public ExMessagePool MessagePool = new ExMessagePool();
        Dictionary<string, ArrayList> FederationList;
        public WorkQueue work;
        DataTable m_WFSetUpTable;
        public DataTable NewWFSetUpTable(string WFType = "", string StartQuery = "YES", string UIMessageID = "", string UIType = "",string UIAddress="")
        {
            DataTable tbWFSetup = m_WFSetUpTable.Clone();
            try
            {
                DataRow dwWFSetup = tbWFSetup.NewRow();
                dwWFSetup["WFType"] = WFType;
                dwWFSetup["StartQuery"] = StartQuery;
                dwWFSetup["UIMessageID"] = UIMessageID;
                dwWFSetup["UIType"] = UIType;
                dwWFSetup["UIAddress"] = UIAddress; 
                tbWFSetup.Rows.Add(dwWFSetup);
            }
            catch (Exception ex)
            {
                Tracer.Error(ex.StackTrace, ex);
            }
            return tbWFSetup;
        }
        /// <summary>
        /// Private constructor for singleton pattern
        /// </summary>
        private EventDispatcher()
        {
            #region Setup the FederationList
            FederationList = new Dictionary<string, ArrayList>();
            Federation = new ArrayList();
            FederationList.Add("UIFederation", Federation);
            Federation = new ArrayList();
            FederationList.Add("WFFederation", Federation);
            Federation = new ArrayList();
            FederationList.Add("HLAFederation", Federation);
            Federation = new ArrayList();
            FederationList.Add("WFServiceFederation", Federation);
            Federation = new ArrayList();
            FederationList.Add("DefaultFederation", Federation);
            #endregion
            m_WFSetUpTable = new DataTable();
            //WFType;StartQuery;UIMessageID
            m_WFSetUpTable.Columns.Add("WFType", typeof(string));
            m_WFSetUpTable.Columns.Add("StartQuery", typeof(string));
            m_WFSetUpTable.Columns.Add("UIMessageID", typeof(string));
            m_WFSetUpTable.Columns.Add("UIType", typeof(string));
            m_WFSetUpTable.Columns.Add("UIAddress", typeof(string));
            this.OnExMessage += new EventHandler<MessageExEventArgs>(EventDispatcher_OnExMessage);
        }

        void EventDispatcher_OnExMessage(object sender, MessageExEventArgs e)
        {
            try
            {
                MessageEx msg = e.What;
                Object Data = e.Data;
                string ClientType = "UIFederate";
                switch (e.EventType)
                { 
                    case EventType.UI2UI:
                        ClientType = "UIFederate";
                        msg.JobType = "UI2UI";
                        break;
                    case EventType.UI2WF:
                        msg.JobType = "UI2WF";
                        ClientType = "WFFederate";
                        break;
                    case EventType.WF2WF:
                        msg.JobType = "WF2WF";
                        ClientType = "WFFederate";
                        break;
                    case EventType.UI2WC:
                        msg.JobType = "UI2WC";
                        ClientType = "WFServiceFederate"; 
                        break;
                    case EventType.WF2UI:
                        ClientType = "UIFederate";
                        msg.JobType = "WF2UI";
                        break; 
                    case EventType.FED2RTI:
                        ClientType = "HLAFederation";
                        msg.JobType = "FED2RTI";
                        break;
                    case EventType.RTI2FED:
                        msg.JobType = "RTI2FED";
                        ClientType = "HLAFederation";
                        break; 
                    default:
                        break; 
                }
                object m_fed = Data; 
                Federate fed = null;
                fed = (Federate)GetFederate(ClientType, msg, m_fed); 
                if (fed != null)
                {
                    fed.MakeUpMessage(ClientType, ref msg, Data, msg.JobID);
                    fed.BuildWorkQueue(msg);
                }
            }
            catch (Exception ex)
            {
                Tracer.Error(ex.StackTrace, ex);
            }
        }
        #endregion 


        #region =================HLA/RTI=================
        public event EventHandler<MessageExEventArgs> OnExMessage;
        public void Publish(MessageEx msg, object Data,EventType type=EventType.UI2UI)
        {
            try
            {   
            if (CheckAccess())
            {
                MessageExEventArgs args = new MessageExEventArgs(msg, Data,type);
                if (OnExMessage != null)
                    OnExMessage(this, args);
            }
            else
                Dispatcher.Invoke(DispatcherPriority.Normal, (ThreadStart)delegate
                {
                    MessageExEventArgs args = new MessageExEventArgs(msg,Data,type);
                    if (OnExMessage != null)
                        OnExMessage(this, args);
                });
            }
            catch (Exception ex)
            {
                Tracer.Error(ex.StackTrace, ex);
            }
        }


     
        #endregion
         


    }
}
